#include"str.hh"
using std::cout;
using std::endl;
using std::cin;

const int String::ksetconstnum=4;
String::String()
    :_pstr(malloc())
{
    cout<<"无参构造"<<endl;
}

String::String(const char* p)
    :_pstr(malloc(p))
{
    cout<<"字符串有参构造"<<endl;
    strcpy(_pstr,p);
}

String::String(const String& str)
    :_pstr(str._pstr)
{
    /* cout<<"有参构造"<<endl; */
     ++*(int*)(_pstr-ksetconstnum);
}
String::~String()
{
    sub();
    if(getnum()==0)
    {
        cout<<"delete    "<<_pstr<<endl;
        delete [](_pstr-ksetconstnum);
        _pstr=nullptr;
    }
}
String &String::operator=(const String& str)
{
    if(this!=&str)
    {
        if(getnum()==1)
        {
            sub();
        delete [](_pstr-ksetconstnum);
        _pstr=nullptr;
        _pstr=str._pstr;
        addnum();
        }
        else 
        {
            sub();
        _pstr=str._pstr;
        addnum();
        }
    }
    /* cout<<"拷贝构造一"<<endl; */
    return *this;
}
String &String::operator=(const char *p)
{
    cout<<"here"<<endl;
    if(strcmp(_pstr,p))
    {
        if(getnum()<=1)
        {
    cout<<"here"<<endl;
        delete [](_pstr-ksetconstnum);
    cout<<"here"<<endl;
        _pstr = nullptr;
    _pstr=malloc(p);
    cout<<_pstr<<endl;
    strcpy(_pstr,p);
    cout<<_pstr<<endl;
        }
        else 
        {
     --*(int*)(_pstr-ksetconstnum);
     _pstr=malloc(p);
     strcpy(_pstr,p);
        }
    }
    /* cout<<"拷贝构造2"<<endl; */
    return *this;
}
//在删除前进行复制可以不考虑访问空的问题
String & String::operator +=(const String & str)
{
    if(getnum()==1)
    {
        size_t num=0;
    sub();
        if(this!=&str)
        {
     num=strlen(_pstr)+strlen(str._pstr);
        }
        else 
        {
            num=2*strlen(str._pstr);
        }
    char * p=malloc(num);
    strcpy(p,_pstr);
    strcat(p,str._pstr);
        delete [](_pstr-ksetconstnum);
    _pstr=p;
    }
    else 
    {
        sub();
     char* p=_pstr;
    size_t num=strlen(p)+strlen(str._pstr);
    _pstr=malloc(num);
    strcpy(_pstr,p);
    strcat(_pstr,str._pstr);

    }
    return *this;
}
String & String::operator +=(const char*p)
{
    if(getnum()==1)
    {
    size_t num=strlen(_pstr)+strlen(p);
    char* pa=malloc(num);
    strcpy(pa,_pstr);
    strcat(pa,p);
        delete [](_pstr-ksetconstnum);
    _pstr=pa;
    }
    else 
    {
     --*(int*)(_pstr-ksetconstnum);
     char* pa=_pstr;
    size_t num=strlen(p)+strlen(p);
    _pstr=malloc(num);
    strcpy(_pstr,pa);
    strcat(_pstr,p);

    }
    return *this;
}

char &String::operator[](std::size_t index)
{
    if(index<strlen(_pstr)-1)
    {
        return _pstr[index];
    }
    else 
    {
      static char sign;
        sign ='\0';
        return sign;
    }
    cout<<"下标运算"<<endl;

}
const char & String::operator[](std::size_t index) const
{
    if(index<strlen(_pstr)-1)
    {
        return _pstr[index];
    }
    else 
    {
      static char sign;
        sign ='\0';
        return sign;
    }
}

std::size_t String::size() const
{
    cout<<"区大小"<<endl;
    return strlen(_pstr);
}
const char* String::c_str() const
{
    cout<<"转换成char*<<"<<endl;
    return _pstr;
}

bool operator==(const String &lhs,const String &rhs)
{
    cout<<"==判断"<<endl;
    return strcmp(lhs._pstr,rhs._pstr)==0;
}
bool operator!=(const String& lhs,const String &rhs)
{
    cout<<"!=判断"<<endl;
    return !(lhs==rhs);
}

bool operator<(const String &lhs,const String &rhs)
{
    
    cout<<"<判断"<<endl;
    return strcmp(lhs._pstr,rhs._pstr)<0;
}
bool operator>(const String &lhs,const String &rhs)
{
    cout<<">判断"<<endl;
    return strcmp(lhs._pstr,rhs._pstr)>0;
}
bool operator<=(const String &lhs,const String &rhs)
{
    cout<<"<=判断"<<endl;
    return strcmp(lhs._pstr,rhs._pstr)<=0;

}
bool operator>=(const String &lhs,const String &rhs)
{
    cout<<">=判断"<<endl;
    return strcmp(lhs._pstr,rhs._pstr)>=0;
}

void String::print()
{

    cout<<"("<<_pstr<<","<<getnum()<<")"<<endl;
}


std::ostream &operator<<(std::ostream &os, const String &s )
{
    /* cout<<"<<重载"<<endl; */
    os<<s._pstr;
    return os;

}
std::istream &operator>>(std::istream &is,  String &s )
{
    /* cout<<">>重载"<<endl; */
    std::vector<char> arr;
    char c;
    while((c=is.get())!='\n')
    {
        if(c==' ')
        {
            break;
        }
        arr.push_back(c);
    }
    size_t num=arr.size();
        s.print();
    if(s.getnum()==1)
    {
        delete [](s._pstr-s.ksetconstnum);
        s._pstr=nullptr;
        s._pstr=s.malloc(num);
        //strncpy可以直接使用
        //strncpy(s,_pstr,arr,num);
        for(size_t i=0;i<num;i++)
        {
            s._pstr[i]=arr[i];
        }

    }
    else 
    {
        s.sub();
        s._pstr=s.malloc(num);
        for(size_t i=0;i<num;i++)
        {
            s._pstr[i]=arr[i];
        }
    }

    return is;
}


String operator+(const String &lhs,const String &rhs)
{
    
    /* cout<<"+++对象相加"<<endl; */
    char* arr =new char[strlen(lhs._pstr)+strlen(rhs._pstr)+1]();
    strcpy(arr,lhs._pstr);
    strcat(arr,rhs._pstr);
    String temp(arr);
    delete []arr;
    return temp;
}
String operator+(const String &lhs,const char *rhs)
{
    char* arr =new char[strlen(lhs._pstr)+strlen(rhs)+1]();
    strcpy(arr,lhs._pstr);
    strcat(arr,rhs);
    String temp(arr);
    delete []arr;
    return temp;
}
String operator+(const char *lhs,const String &rhs)
{
    char* arr =new char[strlen(lhs)+strlen(rhs._pstr)+2]();
    strcpy(arr,lhs);
    strcat(arr,rhs._pstr);
    String temp(arr);
    delete []arr;
    return temp;
}

    char* String::malloc(const char*p)
{
    if(p==nullptr)
    {
        char*_pstr= new char[1+ksetconstnum]()+ksetconstnum;
     *(int*)(_pstr-ksetconstnum)=1;
     return _pstr;
    }
    else 
    {
        char* _pstr= new char[strlen(p)+1+ksetconstnum]()+ksetconstnum;
     *(int*)(_pstr-ksetconstnum)=1;
     return _pstr;
    }
}
    int String::getnum()
{
    return *(int*)(_pstr-ksetconstnum);
}
    void String::addnum()
{
    ++ *(int*)(_pstr-ksetconstnum);
}
void String::sub()
{
    -- *(int*)(_pstr-ksetconstnum);
}
char* String::malloc(size_t num)
{

        char* _pstr= new char[num+1+ksetconstnum]()+ksetconstnum;
     *(int*)(_pstr-ksetconstnum)=1;
     return _pstr;
}
void String::free()
{
    if(getnum()==0)
    {
        delete [](_pstr-ksetconstnum);
    }
}

